package biblioteca.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import java.util.ArrayList;

import bibliOnline.util.details.BookData;
import bibliOnline.db.BookSelector;
import bibliOnline.db.DBConnection;
import bibliOnline.db.DBResponse;
import bibliOnline.db.LoanManager;
import bibliOnline.db.ReservationManager;
import bibliOnline.db.UserManager;
import bibliOnline.util.details.UserDetails;

/**
 * Servlet che gestisce le ricerche.
 * 
 * @author Gabri
 */
public class ComunicaRisultati extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * 
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();
        UserDetails user = (UserDetails) request.getSession().getAttribute("user_data");
        ArrayList<BookData> bookList = new ArrayList(1);
        DBResponse risposta;
        Gson gson = new Gson();

        // Controllo se la ricerca è semplice o avanzata, in base al parametro tipo_comando
        // 6: semplice 7: avanzata
        Integer n_comando = Integer.valueOf(request.getParameter("tipo_comando"));

        // Controllo se il comando non esiste
        if (n_comando == null) {
            risposta = new DBResponse(DBConnection.getProperty("MESSAGE_STRANGE_COMMAND"));
        } // Gestione dei comandi: la numerazione prosegue in continuità con ComunicaClienti
        else {
            switch (n_comando) {

                // Ricerca semplice
                case 6:
                    bookList = BookSelector.simpleDBSearch(request.getParameter("title"), request.getParameter("author"));

                    // Se non ci sono risutati segnalo l'errore
                    if (bookList.isEmpty()) {
                        risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT"));
                    } else {
                        risposta = new DBResponse(bookList);
                    }
                    break;

                // Ricerca complessa
                case 7:
                    bookList = BookSelector.advancedDBSearch(
                            request.getParameter("title"),
                            request.getParameter("author"),
                            request.getParameter("publisher"),
                            request.getParameter("genre"),
                            request.getParameter("year"),
                            request.getParameter("state"));

                    // Se non ci sono risutati segnalo l'errore
                    if (bookList.isEmpty()) {
                        risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT"));
                    } else {
                        risposta = new DBResponse(bookList);
                    }
                    break;

                // Prenotazione
                case 8:
                    try {
                        int time = ReservationManager.addReservation(user, request.getParameter("id"));
                        risposta = new DBResponse(time);
                        risposta.setUsername(user.getUsername());
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;

                // Elenco delle prenotazioni
                case 9:
                    try {
                        bookList = ReservationManager.loadReservations(user);
                        if (bookList.isEmpty()) {
                            risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT_BOOKING"));
                        } else {
                            risposta = new DBResponse(bookList);
                        }
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;

                // Rimuovi prenotazione    
                case 10:
                    try {
                        ReservationManager.removeReservation(user, request.getParameter("id"));
                        risposta = new DBResponse();
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;

                // Elenco utenti    
                case 11:
                    try {
                        risposta = new DBResponse();
                        risposta.insertUserList(UserManager.getUserList(user));
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;
                    
                // Dati del libro
                case 12:
                    try {
                        bookList = BookSelector.bookDataSearch(request.getParameter("id"));
                        risposta = new DBResponse(bookList);
                    } catch (NumberFormatException ex) {
                        risposta = new DBResponse("Il codice inserito non è un codice numerico");
                    } catch (Exception ex) {
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;

                // Prestito    
                case 13:
                    try {
                        LoanManager.loan(user, request.getParameter("customer"), request.getParameter("books"));
                        risposta = new DBResponse();
                    } catch (NumberFormatException ex) {
                        risposta = new DBResponse("Il codice inserito non è un codice numerico");
                    } catch (Exception ex) {
                        risposta = new DBResponse("Impossibile concedere il prestito");
                    }

                    break;

                // Libri in prestito
                case 14:
                    try {
                        bookList = LoanManager.loadBooksOnLoan(user);
                        if (bookList.isEmpty()) {
                            risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT_LOAN"));
                        } else {
                            risposta = new DBResponse(bookList);
                        }
                    } catch (Exception ex) {
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;
                
                // Restituzione
                case 15:
                    try {
                        LoanManager.returnBook(user, request.getParameter("book_id"));
                        risposta = new DBResponse();
                    } catch (NumberFormatException ex) {
                        risposta = new DBResponse("Il codice inserito non è un codice numerico");
                    } catch (Exception ex) {
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;
    
                    
                case 20:
                    try {
                        bookList = LoanManager.loadLoans(user);
                        if (bookList.isEmpty()) {
                            risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT_LOANS"));
                        } else {
                            risposta = new DBResponse(bookList);
                        }
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;   
               case 17: // Inserimento commenti
                    try {
                        String msg_risposta = LoanManager.insertReview(user,request.getParameterMap());
                        risposta = new DBResponse(msg_risposta);
                        
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;   
                case 18: // Visualizzazione commenti x libro
                    try {
                        bookList = LoanManager.loadReviews(user,request.getParameterMap());
                        if (bookList.isEmpty()) {
                            risposta = new DBResponse(DBConnection.getProperty("MESSAGE_EMPTY_RESULT_REVIEWS"));
                        } else {
                            risposta = new DBResponse(bookList);
                        }
                    } catch (Exception ex) {
                        // Messaggio di errore 
                        risposta = new DBResponse(ex.getMessage());
                    }
                    break;    

                default:
                    // Comando errato
                    risposta = new DBResponse(DBConnection.getProperty("MESSAGE_STRANGE_COMMAND"));
            }
        }

        // Trasmetto la risposta, trasformata in Json
        try {
            out.println(gson.toJson(risposta));
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
